package cn.yedong.basic.service.Impl;


import cn.yedong.basic.dto.PhoneCodeDto;
import cn.yedong.basic.exception.BusinessException;
import cn.yedong.basic.service.IVerifyService;
import cn.yedong.basic.util.StrUtils;
import cn.yedong.basic.util.VerifyCodeUtils;
import cn.yedong.user.domain.User;
import cn.yedong.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 获取验证码
 */
@Service
public class VerifyServiceImpl implements IVerifyService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /**
     * 获取图形验证码
     *
     * @param key
     * @return
     */
    @Override
    public String getImageCode(String key) {
        //1.校验
        if (StringUtils.isEmpty(key)) {
            throw new BusinessException("亲，网络繁忙，请稍后再试！");
        }
        //2.生成随机码
        String randomStr = StrUtils.getComplexRandomString(4);
        //3.存入redis设置3分钟有效
        redisTemplate.opsForValue().set(key, randomStr, 3, TimeUnit.MINUTES);
        //4.用base64编码
        String code = VerifyCodeUtils.verifyCode(110, 40, randomStr);
        return code;
    }

    /**
     * 发送手机验证码
     *
     * @param phoneCodeDto
     */
    @Override
    public void sendPhoneCode(PhoneCodeDto phoneCodeDto) {
        String imageCode = phoneCodeDto.getImageCode();
        String imageCodeKey = phoneCodeDto.getImageCodeKey();
        String phone = phoneCodeDto.getPhone();
        //1.空值校验
        if (StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCodeKey) || StringUtils.isEmpty(phone)) {
            throw new BusinessException("信息不能为空！");
        }
        //2.重复注册校验
        User user = userMapper.findByPhone(phone);
        //3.验证码过期校验
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        if (obj == null) {
            throw new BusinessException("图片验证码已过期");
        }
        //4.验证码校验
        if (!imageCode.equals(obj.toString())) {
            throw new BusinessException("图片验证码错误！");
        }
        //从redis中获取验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("register:" + phone);
        //5.判断是否重复获取验证码：[code:时间戳]
        String phoneCode = null;
        //如果过期或者第一次发送
        if (phoneCodeObj == null) {
            //直接重新生成验证码
            phoneCode = StrUtils.getRandomString(4);
        } else {
            //如果redis中有，需要判断是否过了一分钟
            if (System.currentTimeMillis() - Long.parseLong((phoneCodeObj.toString().split(":"))[1]) < 60 * 1000) {
                //两次获取验证码时间小于1分钟
                throw new BusinessException("亲，网络堵塞，请60秒之后再获取！");
            } else {
                //获取数据库中验证码
                phoneCode = (phoneCodeObj.toString().split(":"))[1];
            }
        }
        //将手机验证码存入redis，【register:phone-验证码:时间戳】
        redisTemplate.opsForValue().set("register:" + phone, phoneCode + ":" + System.currentTimeMillis());
//        SmsUtils.sendSms(phone,"【宠物之家】您的手机验证码是"+phoneCode+"请在3分钟内使用！");
        System.out.println("【宠物之家】您的手机验证码是，" + phoneCode + ",请在3分钟内使用！");
    }

    /**
     * 获取微信绑定手机验证码
     *
     * @param phoneCodeDto
     */
    @Override
    public void wechatBinderCode(PhoneCodeDto phoneCodeDto) {
        String phone = phoneCodeDto.getPhone();
        //1.空值校验
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("电话不能为空！");
        }
        //从redis中获取验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("binder:" + phone);
        //5.判断是否重复获取验证码：[code:时间戳]
        String phoneCode = null;
        //如果是第一次发送或已经过期
        if (phoneCodeObj == null) {
            //直接生成新的验证码
            phoneCode = StrUtils.getRandomString(4);
        } else {
            //如果redis中存在；需要判断重发时间
            if (System.currentTimeMillis() - Long.parseLong((phoneCodeObj.toString().split(":"))[1]) < 60 * 1000) {
                //两次获取验证码时间小于1分钟
                throw new BusinessException("亲，网络堵塞，请60秒之后再获取！");
            } else {
                //获取数据库中验证码
                phoneCode = (phoneCodeObj.toString().split(":"))[0];
            }
        }
        //将手机验证码存入redis，【register:phone-验证码:时间戳】
        redisTemplate.opsForValue().set("binder:" + phone, phoneCode + ":" + System.currentTimeMillis());
//        SmsUtils.sendSms(phone,"【宠物之家】您的手机验证码是"+phoneCode+"请在3分钟内使用！");
        System.out.println("【宠物之家-微信绑定】您的手机验证码是," + phoneCode + ",请在3分钟内使用！");
    }
}
